import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './index.less';
import { computedPosition } from '../../main/heightChangeFit';

const MIN_MOVE = 0.1;
export default class SlideRight extends Component {
    static defaultProps = {
        className: '',
        close: null,
    };

    static propTypes = {
        children: PropTypes.element.isRequired,
        // 关闭的事件回调
        close: PropTypes.func,
        className: PropTypes.string,
    };

    state = {
        hide: 1,
    };

    componentDidMount() {}

    // 显示
    show = (left = 1.5) => {
        try {
            let font = $('html')[0].style.fontSize;
            font = parseFloat(font).toFixed(2);
            this.left = left * font;
            this.mainWidth = document.documentElement.clientWidth - this.left;
        } catch (e) {
            console.error('取屏幕rem->px失败');
        }

        this.setState(
            {
                hide: false,
            },
            () => {
                $(this.main).animate(
                    {
                        transform: `translateX(${left}rem)`,
                    },
                    250,
                    'ease-out'
                );
            }
        );
    };

    // 隐藏transform = `translateX(${moved}px)`;
    close = () => {
        $(this.main).animate(
            {
                transform: 'translateX(7.5rem)',
            },
            250,
            'ease-out',
            () => {
                this.props.close && this.props.close();
                this.setState({ hide: true });
            }
        );
    };

    resetMove = () => {
        this.isFirst = true; // 判断是不是水平划动
        this.moved = 0; // 当前总共移动的距离
        this.speed = 0; // 近次移动的速度
        this.isXMoving = false; // 是水平移动,确认是不是点击动作
        this.startPoint = null; // 起点，用于计算moved
        this.lastPoint = null; // 上一次的点，用于计算速度
        this.lastStamp = null; // 上次时间
    };

    getPoint(e) {
        const { pageX, pageY } = e.changedTouches[0] || e.targetTouches[0];
        const x = pageX.toFixed(1);
        const y = pageY.toFixed(1);
        return { x, y };
    }

    touchmove = e => {
        // e.stopPropagation(); // 阻止向子类冒泡
        // e.preventDefault(); // 阻止向默认事件，列表不滚动,但组件内的元素也不能滚动了，麻烦
        const {
            lastStamp, lastPoint, startPoint, isFirst, isXMoving
        } = this;
        this.isFirst = false;

        if (!isXMoving) {
            return;
        }
        // 正在自动完成划动
        if (!startPoint) {
            return;
        }

        const p = this.getPoint(e);
        const moved = Math.round(p.x - startPoint.x);
        const moveDifX = p.x - lastPoint.x;
        const moveDifXabs = Math.abs(moveDifX);
        const moveDifYabs = Math.abs(p.y - lastPoint.y);

        /* 第一次移动判断：
         *       是水平划动 --> 阻止冒泡到子类
         *       是上下划动-- > 退出
         */
        if (isFirst && moveDifYabs > moveDifXabs) {
            this.isXMoving = false;
            return;
        }

        // 移动太小，忽略；多次小移动会累积
        // 禁止左移，或者向右太少
        if (moveDifXabs < MIN_MOVE) {
            return;
        }

        // 获取速度,自动向右滑动时用
        const now = new Date().getTime();
        this.lastStamp = now;
        let speed = moveDifXabs / (now - lastStamp);

        if (speed > 8) {
            speed = 8;
        } else if (speed < 3) {
            speed = 3;
        }
        this.speed = (1 / speed).toFixed(3) * 1000;
        this.moved = moved;
        this.lastPoint = p;
        // 移动对象
        const main = $(this.main)[0];
        const mask = $(this.mask)[0];
        if (!main) {
            return;
        }

        main.style.transition = 'none';
        if (moved > 0) {
            this.cssTransfomRight(main, mask);
        }
    };

    // 右移动画
    cssTransfomRight = (main, mask) => {
        main.style.transform = `translateX(${Math.round(this.left + this.moved)}px)`;
        const opacity = 0.35 * (1 - this.moved / this.mainWidth);
        // mask透明度
        mask.style.background = `rgba(0,0,0,${opacity.toFixed(2)})`;

        // 自动向右滑动
        this.autoForward();
    };

    autoForward = () => {
        const main = $(this.main)[0];
        const mask = $(this.mask)[0];
        if (!main) {
            return false;
        }
        const { mainWidth, speed, moved } = this;
        // 判断是不是已经划过了一半
        if (moved < mainWidth / 2) {
            return false;
        }

        const tranEnd = () => {
            main.removeEventListener('transitionend', tranEnd);
            this.props.close && this.props.close();
            this.setState({ hide: true }, () => {
                main.style.transition = 'none';
                mask.style.background = 'rgba(0,0,0,.35)';
            });
        };

        main.style.transition = `${speed || 100}ms`;
        main.style.transform = 'translateX(7.5rem)';
        mask.style.background = 'rgba(0,0,0,.08)';
        main.addEventListener('transitionend', tranEnd);
        this.resetMove();
        return true;
    };

    // 不判断直接返回，调用之前必须判断是不是已经划过了一半
    autoBack = () => {
        const main = $(this.main)[0];
        const mask = $(this.mask)[0];
        if (!main) {
            return;
        }
        const { left, moved, mainWidth } = this;

        this.moved = 0;
        if (moved === 0) {
            return;
        }

        const tranEndMain = () => {
            main.removeEventListener('transitionend', tranEndMain);

            main.style.transition = 'none';
            mask.style.background = 'rgba(0,0,0,.35)';
        };
        // const tranEndMask = () => {
        //     mask.removeEventListener('transitionend', tranEndMask);
        //
        //     mask.style.transition = 'none';
        //     mask.style.background = 'rgba(0,0,0,.35)';
        // };

        if (moved < 0) {
            mask.style.background = 'rgba(0,0,0,.35)';
        } else {
            main.style.transition = Math.abs(mainWidth / moved) > 4 ? '250ms' : '100ms';
            main.style.transform = `translateX(${left}px)`;
            mask.style.background = 'rgba(0,0,0,.22)';
            main.addEventListener('transitionend', tranEndMain);
        }
    };

    touchStart = e => {
        this.resetMove();
        this.isXMoving = true;
        this.lastPoint = this.getPoint(e);
        this.startPoint = this.lastPoint;
        this.lastStamp = new Date().getTime();
    };

    touchEnd = e => {
        // 点了mask
        // 不正在移动，并且没有点在mask上，则退出
        if (e.target === this.mask) {
            this.close();
            return;
        }

        if (!this.autoForward()) {
            this.autoBack();
        }
    };

    // pc端mask退出
    onClickPc = e => {
        if (e.target === this.mask) {
            this.close();
        }
    };

    // 注册滚动事件
    register = ele => {
        if (ele) {
            ele.addEventListener('touchstart', this.touchStart);
            ele.addEventListener('touchmove', this.touchmove);
            ele.addEventListener('touchend', this.touchEnd);
            WPT.os.pc && ele.addEventListener('click', this.onClickPc);
        }
    };

    render() {
        if (this.state.hide) {
            return null;
        }
        const top = computedPosition(0);
        return (
            <div className={`slide-Right-warp  ${this.props.className}`} ref={this.register} style={{ top }}>
                <div
                    className="s-mask"
                    ref={ele => {
                        this.mask = ele;
                    }}
                    style={{ top }}
                >
                    <div
                        className="main"
                        ref={ele => {
                            this.main = ele;
                        }}
                    >
                        {this.props.children}
                    </div>
                </div>
            </div>
        );
    }
}
